package br.com.esporte.persistence.DAO.impl;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import br.com.base.persistencia.DAO.impl.GenericDAOImpl;
import br.com.esporte.business.impl.util.DataGeneric;
import br.com.esporte.model.DiaPraticadoGrupo;
import br.com.esporte.model.TipoVotacaoEnum;
import br.com.esporte.model.Usuario;
import br.com.esporte.model.Votacao;
import br.com.esporte.persistence.DAO.VotacaoDAO;
import br.com.esporte.persistence.filter.FiltroVotacao;

/**
 * 
 * @author Milton Domingues
 *
 */
@Repository
public class VotacaoDAOImpl extends GenericDAOImpl<Votacao, Long, FiltroVotacao> implements VotacaoDAO {

	public VotacaoDAOImpl() {
		super(Votacao.class);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<DataGeneric<Usuario, DataGeneric<Integer, Boolean>>> consultarMaiorVotadoQtdVotos(DiaPraticadoGrupo dia, TipoVotacaoEnum tipo) {

		StringBuilder hql = new StringBuilder();
		hql.append("SELECT grupoParticipante.participante ");
		hql.append("FROM GrupoParticipante grupoParticipante ");
		hql.append("WHERE grupoParticipante.grupo = :grupo");

		Query query = createQuery(hql.toString());
		query.setParameter("grupo", dia.getGrupo());

		List<Usuario> usuarios = query.getResultList();

		StringBuilder hql2 = new StringBuilder();
		hql2.append("SELECT vo.usuarioVotado.id, COUNT(vo.usuarioVotado) ");
		hql2.append("FROM Votacao vo WHERE vo.tipoVotacao = :tipo AND dia = :dia ");
		hql2.append("GROUP BY vo.usuarioVotado.id ORDER BY 2 DESC");

		Query query2 = createQuery(hql2.toString());
		query2.setParameter("dia", dia);
		query2.setParameter("tipo", tipo);

		List<Object[]> list = query2.getResultList();

		List<DataGeneric<Usuario, DataGeneric<Integer, Boolean>>> lista = new ArrayList<DataGeneric<Usuario,DataGeneric<Integer, Boolean>>>();

		popularListDataGeneric(lista, usuarios, list);


		return lista;
	}

	@SuppressWarnings("unchecked")
	@Override
	public DataGeneric<Usuario, Integer> consultarMaiorVotadoTipoDiaPraticado(DiaPraticadoGrupo dia, TipoVotacaoEnum tipo) {
		StringBuilder hql = new StringBuilder();
		hql.append("SELECT vo.usuarioVotado.id, COUNT(vo.usuarioVotado) ");
		hql.append("FROM Votacao vo WHERE vo.tipoVotacao = :tipo AND dia = :dia ");
		hql.append("GROUP BY vo.usuarioVotado.id ORDER BY 2 DESC");

		Query query = createQuery(hql.toString());
		query.setParameter("dia", dia);
		query.setParameter("tipo", tipo);

		DataGeneric<Usuario, Integer> obj = new DataGeneric<Usuario, Integer>();

		List<Object[]> list = query.getResultList();
		if((list != null) && (list.size() > 0)){
			Long idUsuario = (Long) list.get(0)[0];

			if(idUsuario > 0) {
				StringBuilder hqlUser = new StringBuilder();
				hqlUser.append("FROM Usuario u WHERE u.id = :id");

				Query query2 = createQuery(hqlUser.toString());
				query2.setParameter("id", idUsuario);

				obj.setObject1((Usuario) query2.getSingleResult());
				obj.setObject2(((Long) list.get(0)[1]).intValue());
			}
		}

		return obj;
	}

	private void popularListDataGeneric(List<DataGeneric<Usuario, DataGeneric<Integer, Boolean>>> lista, List<Usuario> usuarios, List<Object[]> list ){
		DataGeneric<Integer, Boolean> dataMaior = new DataGeneric<Integer, Boolean>(0, false);
		for (Usuario usuario : usuarios) {
			boolean contem = false;
			DataGeneric<Usuario, DataGeneric<Integer, Boolean>> obj = new DataGeneric<Usuario, DataGeneric<Integer, Boolean>>();
			obj.setObject1(usuario);
			for (Object[] objects : list) {
				Long idUsuario = (Long) objects[0];
				if(usuario.getId().equals(idUsuario)){
					contem = true;
					Integer qtdVotos = ((Long) objects[1]).intValue();
					DataGeneric<Integer, Boolean> data = new DataGeneric<Integer, Boolean>(qtdVotos, false);
					obj.setObject2(data);
					if((dataMaior != null) && (dataMaior.getObject1() < data.getObject1())){
						dataMaior = data;
					}
				}
			}

			if(!contem){
				obj.setObject2(new DataGeneric<Integer, Boolean>(0, false));
			}

			lista.add(obj);
		}

		if(dataMaior.getObject1() > 0){
			dataMaior.setObject2(true);
		}
	}

}
